﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace odinshrine
{

    public class Game1 : Microsoft.Xna.Framework.Game
    {
        const int canon = 25;
        const int nbre_balles = 100;

        public GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Sprite balle;
        GestionEnnemi gEnnemi;
        Joueur player;
        KeyboardState clavier;
        Interface jeu;
        Menu menu;
        GestionPhysics physEngine;
        Vector2 directionTir;
        TimeSpan timer_bouton;
        Random rand;
        map Map;
        Pause menuPause;
        MouseState mouse;
        Armerie armerie;
        bool win = false;
        SpriteFont font;
        Soldat soldat; //Pour tester!jio
        histoire scenario;

        

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            graphics.PreferredBackBufferWidth = 800;
            graphics.PreferredBackBufferHeight = 600;
            graphics.ApplyChanges();

            IsMouseVisible = true;

            player = new Joueur(6);
            physEngine = new GestionPhysics();
            directionTir = new Vector2(1, 0);
            balle = new Sprite();
            timer_bouton = TimeSpan.Zero;
            Map = new map(@"map4.txt");
            menuPause = new Pause();
            menu = new Menu();
            gEnnemi = new GestionEnnemi();
            rand = new Random();
            jeu = new Interface();
            armerie = new Armerie();
            Son.Init();
            font = Content.Load<SpriteFont>("string");
            soldat = new Soldat(Content);
            scenario = new histoire();

            Map.Init();

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            armerie.Load(Content);
            player.Load(Content, player, physEngine);
            balle.Load(Content, "images/balle");
            jeu.Load(Content, graphics); //Charge le background, les points
            gEnnemi.LoadEnnemi(Content, physEngine);
            menuPause.initPause(Content);
            Map.Load2(Content, gEnnemi);
            menu.Load(Content);
            scenario.Chargement_1(Content);
        }

        protected override void UnloadContent()
        {

        }

        protected override void Update(GameTime gameTime)
        {
            // Gestion clavier
            clavier = Keyboard.GetState();
            Son.Gestion(clavier, player, gameTime);

            if (!Pause.pause && !win)
            {
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();

                if (!Mainmenu.menu_on)
                {
                    player.Deplacements(clavier, player, physEngine);

                    if (clavier.IsKeyDown(Commandes.commandes[0]))
                    {
                        player.movingleft = true;
                    }

                    if (clavier.IsKeyDown(Commandes.commandes[1]))
                    {
                        player.movingright = true;

                        if (player.Position.X + player.width >= graphics.PreferredBackBufferWidth / 2) // On scroll quand le joueur arrive au milieu de l'ecran seulement
                        {
                            // Scrolling
                            player.Position = player.lastPos;
                            jeu.scrolling(jeu.fond1, jeu.fond2,gEnnemi, player.Vitesse, Map);
                        }

                        directionTir.X = 1;
                        directionTir.Y = 0;
                    }

                    if (clavier.IsKeyDown(Keys.S))
                    {
                        player.aimlow = true;
                    }
                   
                    if (clavier.IsKeyDown(Keys.W))
                    {
                        player.aimup = true;
                    }

                    if (clavier.IsKeyDown(Keys.Space))
                    {
                        if (!player.sauter)
                        {
                            player.Position.Y -= 5;
                        }
                        player.sauter = true; // true: le joueur est dans le mouvement du saut, en plein vol | false: le joueur est entrain de marcher ou vient juste d'atterrir apres un saut
                    }

                    if (clavier.IsKeyDown(Keys.P))
                    {
                        Pause.pause = true;
                    }

                    if (clavier.IsKeyDown(Keys.Escape))
                    {
                        this.Exit();
                    }

                    jeu.Gestion(gameTime);
                    player.TirJoueur(clavier, Map, physEngine, balle, gEnnemi, jeu, gameTime);
                    physEngine.Saut(player, graphics, gameTime);
                    physEngine.Saut(soldat, graphics, gameTime);
                    physEngine.Maping(player, graphics, Map);
                    Armerie.changerArme(clavier, player);
                    gEnnemi.EnnemisIA(player, gameTime, Map, physEngine);
                    player.Animation(physEngine); //Gere l'animation du joueur
                    player.AngleMe(gameTime);

                    if (Map.coefx >= 6000)
                    {
                        win = true;
                    }


                    // Update de variables
                    player.lastPos = player.Position;
                    timer_bouton += gameTime.ElapsedGameTime;
                    player.Update(gameTime);
                }
                else
                {
                    //If menu_on
                    mouse = Mouse.GetState();
                    menu.Gestion(mouse, clavier, this, gameTime);
                    scenario.Update(gameTime, Content, clavier, graphics);
                }
            }
            else
            {
                mouse = Mouse.GetState();
                menuPause.timer_pause += gameTime.ElapsedGameTime;
                menuPause.Gestion(this, Content, mouse, clavier);
            }

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Green);

            spriteBatch.Begin();

            if (!Mainmenu.menu_on)
            {
                jeu.Draw(spriteBatch, player);
                player.Draw(spriteBatch);
                gEnnemi.DrawEnnemi(spriteBatch, graphics);
                player.ballesListe.Draw(spriteBatch, balle.Texture, graphics);
                Map.Draw2(spriteBatch, graphics, gEnnemi);
                spriteBatch.DrawString(font, "X" + soldat.X, new Vector2(20, 20), Color.Black);
                spriteBatch.DrawString(font, "Y" + soldat.Y, new Vector2(20, 60), Color.Black);
                //TEST PATHFINDIG
                int accu = 20;
                foreach(BadGuys bad in gEnnemi.tabEnnemi1)
                {
                    soldat.findStruct(player, Map, bad, 100, 100);
                }
                try
                {
                    foreach (Structure s in soldat.pathEvaluation())
                    {
                        spriteBatch.DrawString(font, s.beg.Elts.structIndic.ToString(), new Vector2(accu, 160), Color.Black);
                        accu += 20;
                    }
                }
                catch { }
                /*foreach (LinkedList<Structure> list in soldat.pathsList)
                {
                    foreach (Structure s in list)
                    {
                        spriteBatch.DrawString(font, s.beg.Elts.structIndic.ToString(), new Vector2(accu, 100), Color.Black);
                        accu += 20;
                    }
                }    */  
                try
                {
                    spriteBatch.DrawString(font, "STRUCT " + Map.structlist[Map.caisseList2[soldat.X, soldat.Y].structIndic].beg.Elts.structIndic, new Vector2(20, 100), Color.Black);
                }
                catch { }
                //FIN TEST
                if (Pause.pause)
                {
                    menuPause.drawPause(spriteBatch, mouse);
                }
            }
            else
            {
                menu.Draw(spriteBatch, mouse);
                scenario.Draw(spriteBatch, Content, graphics) ;
            }
            
            spriteBatch.End();
            base.Draw(gameTime);
        }

    }
}